package com.faxsun.core.persist.dao.impl;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import mtons.modules.persist.impl.DaoImpl;
import mtons.modules.pojos.Page;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

import com.faxsun.core.persist.dao.LiveDao;
import com.faxsun.core.persist.entity.LivePO;

public class LiveDaoImpl extends DaoImpl<LivePO>implements LiveDao {

	private static final int recentRadiusInMinutes = 60 * 24 * 30 * 2;// generally
																		// 2months/60days

	private static final long serialVersionUID = -2498977616045100304L;

	protected LiveDaoImpl() {
		super(LivePO.class);
	}

	@Transactional
	@Override
	public LivePO get(Serializable id) {
		return super.get(id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<LivePO> listRecent(Page page, Date current) {
		Criteria criteria = this.createCriteria();

		criteria.setFirstResult(page.getFirstResult());
		criteria.setMaxResults(page.getMaxResults());

		criteria.addOrder(Order.desc("startTime"));

		Calendar cal = Calendar.getInstance();
		cal.setTime(current);
		cal.add(Calendar.MINUTE, recentRadiusInMinutes);
		Date ahead = cal.getTime();

		cal.setTime(current);
		cal.add(Calendar.MINUTE, (0 - recentRadiusInMinutes));
		Date before = cal.getTime();

		criteria.add(Restrictions.le("startTime", ahead));
		criteria.add(Restrictions.ge("startTime", before));

		criteria.add(Restrictions.eq("isSelected", LivePO.SELECTED));

		List<LivePO> ret = criteria.list();
		page.setResults(ret);
		return ret;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<LivePO> listFinished(Page page, Date current) {
		Criteria criteria = this.createCriteria();

		criteria.setFirstResult(page.getFirstResult());
		criteria.setMaxResults(page.getMaxResults());

		criteria.addOrder(Order.desc("startTime"));
		criteria.add(Restrictions.lt("endTime", current));

		criteria.add(Restrictions.eq("isSelected", LivePO.SELECTED));

		List<LivePO> ret = criteria.list();
		page.setResults(ret);
		return ret;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<LivePO> listActive(Page page, Date current) {
		Criteria criteria = this.createCriteria();

		criteria.setFirstResult(page.getFirstResult());
		criteria.setMaxResults(page.getMaxResults());

		criteria.addOrder(Order.desc("startTime"));

		criteria.add(Restrictions.le("startTime", current));
		criteria.add(Restrictions.ge("endTime", current));

		criteria.add(Restrictions.eq("isSelected", LivePO.SELECTED));

		List<LivePO> ret = criteria.list();
		page.setResults(ret);
		return ret;
	}

	@Override
	@Transactional
	public LivePO findByTopic(String topic) {
		return findUniqueBy("topic", topic);
	}

	@Override
	public List<LivePO> listAllEvent(Page page, boolean isAdminEnd) {
		PagingQuery<LivePO> q = pagingQuery(page);
		q.desc("startTime");
		if (!isAdminEnd)
			q.add(Restrictions.eq("isSelected", LivePO.SELECTED));
		return q.list();
	}

	@Override
	public List<LivePO> listFuture(Page page, Date current) {
		PagingQuery<LivePO> q = pagingQuery(page);

		q.asc("startTime");
		q.add(Restrictions.gt("startTime", current));
		q.add(Restrictions.eq("isSelected", LivePO.SELECTED));
		List<LivePO> ret = q.list();
		return ret;
	}

	@Override
	public List<LivePO> listPresent(Page page, Date current) {
		PagingQuery<LivePO> q = pagingQuery(page);

		q.asc("startTime");
		q.add(Restrictions.le("startTime", current));
		q.add(Restrictions.ge("endTime", current));
		q.add(Restrictions.eq("isSelected", LivePO.SELECTED));
		List<LivePO> ret = q.list();
		return ret;
	}

	@Override
	public List<LivePO> listPast(Page page, Date current) {
		PagingQuery<LivePO> q = pagingQuery(page);

		q.asc("startTime");
		q.add(Restrictions.lt("endTime", current));
		q.add(Restrictions.eq("isSelected", LivePO.SELECTED));
		List<LivePO> ret = q.list();
		return ret;
	}

	@Override
	public int countBySimlarTopic(String topic) {
		Criteria criteria = this.createCriteria();
		criteria.add(Restrictions.like("topic", topic, MatchMode.START));
		criteria.setProjection(Projections.count("id"));
		Number count = (Number) criteria.uniqueResult();
		return count.intValue();
	}

	@Override
	public int countAllLive() {
		Criteria criteria = this.createCriteria();
		criteria.setProjection(Projections.count("id"));
		Number count = (Number) criteria.uniqueResult();
		return count.intValue();
	}

}
